package com.core.system.service.impl;

import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.core.config.crud.CrudServiceImpl;
import com.core.system.dao.SystemDictTypeMapper;
import com.core.system.service.ISystemDictItemService;
import com.core.system.service.ISystemDictTypeService;
import com.core.system.utils.ConvertUtils;
import com.pojo.dto.SystemDictItemDto;
import com.pojo.dto.SystemDictTypeDto;
import com.pojo.entity.SystemDictItemEntity;
import com.pojo.entity.SystemDictTypeEntity;
import com.pojo.parent.BaseDto;
import com.pojo.resp.dictType.DictTypePageResp;
import com.utility.exception.ServiceException;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统字典类型表 服务实现类
 * </p>
 *
 * @author hewei
 * @since 2023-12-31
 */
@Service
public class SystemDictTypeServiceImpl extends CrudServiceImpl<SystemDictTypeMapper, SystemDictTypeEntity, SystemDictTypeDto> implements ISystemDictTypeService {

    /**
     * 字典条目表
     */
    private final ISystemDictItemService itemService;
    /**
     * 缓存工具类
     */
//    private final RedisUtil redisUtil;

    public SystemDictTypeServiceImpl(ISystemDictItemService itemService
                                     /*RedisUtil redisUtil*/) {
        this.itemService = itemService;
//        this.redisUtil = redisUtil;
    }


    // 字典类型code
    private static final String DICT_TYPE_CODE = "dictTypeCode";
    /**
     * 字典名称
     */
    private static final String DICT_TYPE_NAME = "dictTypeName";
    /**
     * 排序字段
     */
    private static final String SORT = "sort";
    /**
     * id
     */
    private static final String ID = "id";

    private static final String DICT_TYPE_IDS = "dictTypeIds";
    /**
     * @param paramMap 各自的实体类字段
     * @return
     */
    @Override
    public LambdaQueryWrapper<SystemDictTypeEntity> getLambdaQueryWrapper(Map<String,Object> paramMap) {
        LambdaQueryWrapper<SystemDictTypeEntity> wrapper = Wrappers.lambdaQuery(SystemDictTypeEntity.class);
        Object dictTypeName = paramMap.get(DICT_TYPE_NAME);
        Object id = paramMap.get(ID);
        Object dictTypeCode = paramMap.get(DICT_TYPE_CODE);
        Object sort = paramMap.get(SORT);
        wrapper.eq(ObjectUtils.isNotEmpty(id),SystemDictTypeEntity::getId,id);
        wrapper.like(ObjectUtils.isNotEmpty(dictTypeName),SystemDictTypeEntity::getDictTypeName,dictTypeName);
        wrapper.like(ObjectUtils.isNotEmpty(dictTypeCode),SystemDictTypeEntity::getDictTypeCode,dictTypeCode);
        wrapper.like(ObjectUtils.isNotEmpty(sort),SystemDictTypeEntity::getSort,sort);
        return wrapper;
    }

    /**
     * 公共方法
     * 验证实体类字段
     * @param dto 实体字段
     */
    @Override
    public void verify(SystemDictTypeDto dto) {
        //判断dictTypeName是否存在 并且 去除自身
        LambdaQueryWrapper<SystemDictTypeEntity> wrapper = Wrappers.lambdaQuery(SystemDictTypeEntity.class);
        wrapper.eq(SystemDictTypeEntity::getDictTypeName, dto.getDictTypeName());
        wrapperVerify(wrapper,dto.getId(),dto.getDictTypeName()+"已存在");
        wrapper.clear();
        wrapper.eq(SystemDictTypeEntity::getDictTypeCode, dto.getDictTypeCode());
        wrapperVerify(wrapper,dto.getId(),dto.getDictTypeCode()+"已存在");
    }

    /**
     * 公共方法查询条件
     * @param wrapper lambdaQueryWrapper 对象
     * @param id id 主键id 判断新增还是编辑
     * @param msg 异常描述
     */
    public void wrapperVerify(LambdaQueryWrapper<SystemDictTypeEntity> wrapper,Long id,String msg) {
        //判断只查询id字段 提高效率
        wrapper.select(SystemDictTypeEntity::getId);
        List<SystemDictTypeEntity> list = list(wrapper);
        /*
            id为空 并且 名称查询列表不为空  = 名称已存在
               ||
            id不为空 并且 名称查询列表不为空 并且 名称不等于自身 = 名称已存在
         */
        if (( !list.isEmpty() &&  Objects.isNull(id))
                ||
            (Objects.nonNull(id) && !list.isEmpty() && !Objects.equals(list.get(0).getId(),id))
        ) {
            throw new ServiceException(msg);
        }
    }

    /**
     * 自定义分页
     * @param paramMap
     * @return
     */
    @Override
    public List<DictTypePageResp> dictTypeList(Map<String, Object> paramMap) {
        List<SystemDictTypeDto> dictTypeList = super.list(paramMap);
        Object dictTypeCode = paramMap.get(DICT_TYPE_CODE);
        List<SystemDictItemDto> itemDtoList = listByDictTypeId(dictTypeList,Objects.isNull(dictTypeCode)?null:dictTypeCode.toString());
        //组装返回分页数据
        List<DictTypePageResp> pageRespList = new ArrayList<>();
        // 在用对比方法得出对应下级集合，避免重复查库
        dictTypeList.forEach( l->{
            List<SystemDictItemDto> itemEntityList =
                    itemDtoList.stream().filter(item -> Objects.equals(item.getDictTypeId(),l.getId())).collect(Collectors.toList());
            DictTypePageResp dictTypePageResp = ConvertUtils.Convert(l, DictTypePageResp.class);
            dictTypePageResp.setChildren(ConvertUtils.Convert(itemEntityList, SystemDictItemDto.class));
            pageRespList.add(dictTypePageResp);
        });
        return pageRespList;
    }

    /**
     * 根据父级code查询缓存下级数据
     * @param dictTypeList 父级列表集合
     * @param dictTypeCode 父级code 用于查询缓存
     * @return
     */
    public List<SystemDictItemDto> listByDictTypeId(List<SystemDictTypeDto> dictTypeList,Object dictTypeCode) {
        /**
         *  1.查询缓存
         */
        if (Objects.nonNull(dictTypeCode)){
//            if (redisUtil.hasKey(REFRESH_CACHE_PREFIX+dictTypeCode)) {
//                return redisUtil.lGet(REFRESH_CACHE_PREFIX  + dictTypeCode, 0, -1, SystemDictItemDto.class);
//            }else {
//                // 如果没有则塞入
//                this.refreshCache(dictTypeCode.toString());
//            }
        }
        // 转换得出字典类型id
        List<Long> dictTypeIds = dictTypeList.stream().map(BaseDto::getId).collect(Collectors.toList());
        // 封装参数一次性查询分页所有的下级条目列表
        Map<String,Object> map = new HashMap<>();
        map.put(DICT_TYPE_IDS,dictTypeIds);

        return itemService.list(map);
    }

    /**
     * 根据父级id查询下级数据
     * @param dictTypeList 父级列表集合
     * @return
     */
    public List<SystemDictItemDto> listByDictTypeId(List<SystemDictTypeDto> dictTypeList) {
        return listByDictTypeId(dictTypeList,null);
    }

    /**
     * 刷新缓存
     * @param dictTypeCode 字典类型
     */
    private static final String REFRESH_CACHE_PREFIX = "systemDictType:refreshCache:";
    @Override
    public void refreshCache(String dictTypeCode) {
        // dictTypeCode 为空查询所有如果不为空查询对应code的类型编号数据
        Map<String,Object> map = new HashMap<>();
        if (StringUtils.isNotBlank(dictTypeCode)){
            map.put("dictTypeId",onCodeSelectId(dictTypeCode));
            List<SystemDictItemDto> itemDtoList = itemService.list(map);
//            redisUtil.del(REFRESH_CACHE_PREFIX+dictTypeCode);
//            if (CollectionUtils.isNotEmpty(itemDtoList)){
//                itemDtoList.forEach(lit -> redisUtil.lSet(REFRESH_CACHE_PREFIX+dictTypeCode, lit,86400));
//            }
            return;
        }
        List<SystemDictTypeDto> dictCodelist = list(map);
        List<SystemDictItemDto> itemDtoList = listByDictTypeId(dictCodelist);
        // 在用对比方法得出对应下级集合，避免重复查库
//        redisUtil.del(REFRESH_CACHE_PREFIX+dictTypeCode);
        dictCodelist.forEach( l->{
            List<SystemDictItemDto> itemEntityList =
                    itemDtoList.stream().filter(item -> Objects.equals(item.getDictTypeId(),l.getId())).collect(Collectors.toList());
//            if (CollectionUtils.isNotEmpty(itemEntityList)){
//                itemEntityList.forEach(lit -> redisUtil.lSet(REFRESH_CACHE_PREFIX+l.getDictTypeCode(),lit,86400));
//            }
        });
    }

    /**
     * 根据code获取Id
     * @param dictTypeCode 字典类型
     * @return
     */
    @Override
    public Long onCodeSelectId(String dictTypeCode) {
        Map<String,Object> map = new HashMap<>();
        map.put(DICT_TYPE_CODE,dictTypeCode);
        List<SystemDictTypeDto> itemDtoList = list(map);
//        if (CollectionUtils.isEmpty(itemDtoList)){
//            throw new ServiceException("没有找到对应字典类型");
//        }
        return itemDtoList.get(0).getId();
    }

    @Override
    public void remove(Long id){
        LambdaQueryWrapper<SystemDictItemEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SystemDictItemEntity::getId)
                .eq(SystemDictItemEntity::getDictTypeId,id);
        // 删除之前先查询出下级条目
        List<SystemDictItemEntity> list = itemService.list(wrapper
        );
//        if(!Collections.isEmpty(list)){
//            throw new ServiceException("请先删除下级条目");
//        }
        super.remove(id);
    }
}
